package lab.cadl.lirui.markdown.core

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.subcommands
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.validate
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.validate
import com.github.ajalt.clikt.parameters.types.choice
import lab.cadl.lirui.markdown.core.parser.MarkdownParserFactory
import lab.cadl.lirui.markdown.core.renderers.HtmlRenderer
import lab.cadl.lirui.markdown.core.renderers.RenderOption
import lab.cadl.lirui.markdown.core.renderers.WordRenderer
import lab.cadl.lirui.markdown.core.utils.ImageCacheImpl
import org.apache.logging.log4j.core.config.ConfigurationSource
import org.apache.logging.log4j.core.config.Configurator
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths

class Main : CliktCommand() {
    override fun run() {
    }
}

enum class OutputFormat {
    WORD, HTML
}

class Generate : CliktCommand(name = "gen") {
    private val inputFile by argument("INPUT_FILE").validate {
        require(File(it).exists()) {
            "input file '$it' not exists"
        }
    }

    private val format by option("-f", "--format").choice("word" to OutputFormat.WORD,
            "html" to OutputFormat.HTML).default(OutputFormat.WORD)

    private val outputDir by option("-d", "--dir").default("")
            .validate {
                if (!it.isBlank()) {
                    val path = Paths.get(it)
                    if (!path.toFile().exists()) {
                        Files.createDirectories(path)
                    }

                    require(path.toFile().exists()) {
                        "cannot create output directory"
                    }
                }
            }

    private val templateFile by option("-t", "--template").default("")
            .validate {
                if (!it.isBlank()) {
                    val path = Paths.get(it)
                    require(path.toFile().exists()) {
                        "template file/dir not exists"
                    }
                }
            }

    override fun run() {
        val baseDir = File(inputFile).parent ?: "./"
        val imageCache = ImageCacheImpl(baseDir)
        val document = MarkdownParserFactory(imageCache).create().parse(File(inputFile))

        val renderer = when (format) {
            OutputFormat.WORD -> WordRenderer()
            OutputFormat.HTML -> HtmlRenderer()
        }

        val originName = File(inputFile).nameWithoutExtension
        val destDir = if (outputDir.isBlank()) {
            baseDir
        } else {
            outputDir
        }
        renderer.render(document, RenderOption(destDir, originName, templateFile, imageCache, renderer.defaultCustomOption()))
    }
}

fun main(args: Array<String>) {
    val source = ConfigurationSource(Main::class.java.getResourceAsStream("log4j2.xml"))
    Configurator.initialize(null, source)

    Main().subcommands(Generate()).main(args)
}
